package com.lagou.edu.filter;

import org.apache.commons.lang.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.core.io.buffer.DataBuffer;
import org.springframework.http.HttpCookie;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.client.RestTemplate;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.*;

@Component
@RefreshScope
public class MyFilter implements GlobalFilter, Ordered {

    @Autowired
    private RestTemplate restTemplate;

    // 防暴刷限制时间
    @Value("${limit.time}")
    private int limitTime;

    //防暴刷限制次数
    @Value("${limit.times}")
    private int limitTimes;

    private static Map<String, List<Long>> allIp = new HashMap();

    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 从上下⽂中取出request和response对象
        ServerHttpRequest request = exchange.getRequest();
        ServerHttpResponse response = exchange.getResponse();

        // 从request对象中获取客户端ip
        String clientIp = request.getRemoteAddress().getHostString();

        String path = request.getPath().toString();

        // 防爆刷
        System.out.println("===========path:" + path);
        if (path.contains("/user/register")) {
            System.out.println("clientIp" + clientIp);
            System.out.println("allIp" + allIp);
            List<Long> list;
            if (allIp.containsKey(clientIp)) {// 已有访问记录
                list = allIp.get(clientIp);// 此ip的所有访问时间
            } else {// 无访问记录
                list = new ArrayList<>();// 新建此ip的访问记录
            }

            long now = System.currentTimeMillis();

            // 限制时间内访问的次数
            int times = 0;
            Collections.sort(list);
            List<Long> newList = new ArrayList<>();
            for (int i = list.size() - 1; i >= 0; i--) {
                Long time = list.get(i);
                if (time > now - limitTime * 60 * 1000) {// 记录在限制时间内
                    times++;
                    newList.add(time);
                    break;
                }
            }

            // 删除超出限制时间的记录
            Collections.reverse(newList);
            list = newList;

            if (times > limitTimes) {
                response.setStatusCode(HttpStatus.FORBIDDEN); // 状态码
                String data = "too times to register";
                DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
                return response.writeWith(Mono.just(wrap));
            }

            list.add(now);// 记录当前时间

            allIp.put(clientIp, list);

        }

        // token验证(仅过滤email服务)
        MultiValueMap<String, HttpCookie> cookies = request.getCookies();

        if (path.contains("/email/")) {
            boolean flag = true;

            if (!cookies.isEmpty()) {
                List<HttpCookie> token = cookies.get("token");
                if (token != null && token.size() > 0) {
                    HttpCookie httpCookie = token.get(0);
                    String cookieValue = httpCookie.getValue();
                    System.out.println("cookie：" + cookieValue);

                    // 全局验证token
                    String url = "http://lagou-service-user/user/info/" + cookieValue;
                    String email = restTemplate.getForObject(url, String.class);

                    if (!StringUtils.isEmpty(email)) {
                        flag = false;

                        // 验证通过
                    }
                }

            }

            if (flag) {
                response.setStatusCode(HttpStatus.FOUND); // 状态码
                String data = "no token";
                DataBuffer wrap = response.bufferFactory().wrap(data.getBytes());
//                response.getHeaders().set("Location", "http://www.test.com/static/login.html");
//                return exchange.getResponse().setComplete();
                return response.writeWith(Mono.just(wrap));
            }

        }

        // 放行，执行后续的过滤器
        return chain.filter(exchange);
    }

    @Override
    public int getOrder() {
        return 0;
    }
}
